package com.hrms.common.utils;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RequestUtil {
    /**
     * 获取request中的参数集合转对象
     * 用法：User user = (User) RequestUtil.getParameterObject(request, new User())
     * @param request obj
     * @return
     */
    public static Object getParameterObject(HttpServletRequest request, Object obj) {
        Map map = request.getParameterMap();
        try {
            BeanUtils.populate(obj, map);
            return obj;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取request中的参数集合转对象
     * 用法：User user = (User) RequestUtil.getParameterObject(request, new User())
     * @param request obj
     * @return
     */
    public static Object getObjectByRequest(Class<?> clazz, HttpServletRequest request) throws ClassNotFoundException, ParameterError {
        Object entity = null;
        try{
            entity = clazz.getDeclaredConstructor().newInstance();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                String value = request.getParameter(field.getName());
                if(value==null){
                    continue;
                }
                String filedName = field.getName();
                Class<?> filedType = field.getType();
                String setterName = "set"+ StringUtils.capitalize(filedName);
                Method setterMethod;
                try {
                    setterMethod = clazz.getMethod(setterName,filedType);
                } catch (NoSuchMethodException e) {
                    setterMethod = null;
                    e.printStackTrace();
                }
                if(setterMethod==null){
                    continue;
                }
                setterMethod.invoke(entity, TypeUtils.stringToTarget(value,filedType));
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ParameterError("request参数错误,无法获得对应实例类");
        }
        return entity;
    }

    public static class ParameterError extends Exception{
        private String message;
        public ParameterError(String message){
            super(message);
            this.message = message;
        }
    }

    /**
     * 获取request中的参数集合转Map
     * Map<String,String> parameterMap = RequestUtil.getParameterMap(request)
     * @param request
     * @return
     */
    public Map<String, String> getParameterMap(HttpServletRequest request) {
        Map<String, String> map = new HashMap<>();
        Enumeration<String> paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = paramNames.nextElement();
            String[] paramValues = request.getParameterValues(paramName);
            if (paramValues.length == 1) {
                String paramValue = paramValues[0];
                if (paramValue.length() != 0) {
                    map.put(paramName, paramValue);
                }
            }
        }
        return map;
    }


    public static Map<String, Object> getParameterValueMap(HttpServletRequest request, boolean remainArray, boolean isSecure) {
        Map<String, Object> map = new HashMap();
        Enumeration params = request.getParameterNames();

        while(params.hasMoreElements()) {
            String key = params.nextElement().toString();
            String[] values = request.getParameterValues(key);
            if (values != null) {
                String tmpValue;
                if (values.length == 1) {
                    tmpValue = values[0];
                    if (tmpValue != null) {
                        tmpValue = tmpValue.trim();
                        if (!tmpValue.equals("")) {
                            if (isSecure) {
                                tmpValue = filterInject(tmpValue);
                            }

                            if (!tmpValue.equals("")) {
                                map.put(key, tmpValue);
                            }
                        }
                    }
                } else {
                    tmpValue = getByAry(values, isSecure);
                    if (tmpValue.length() > 0) {
                        if (remainArray) {
                            map.put(key, tmpValue.split(","));
                        } else {
                            map.put(key, tmpValue);
                        }
                    }
                }
            }
        }

        return map;
    }

    public static String filterInject(String str) {
        String injectstr = "\\||;|exec|insert|select|delete|update|count|chr|truncate|char";
        Pattern regex = Pattern.compile(injectstr, 226);
        Matcher matcher = regex.matcher(str);
        str = matcher.replaceAll("");
        str = str.replace("'", "''");
        str = str.replace("-", "—");
        str = str.replace("(", "（");
        str = str.replace(")", "）");
        str = str.replace("%", "％");
        return str;
    }

    private static String getByAry(String[] aryTmp, boolean isSecure) {
        String rtn = "";

        for(int i = 0; i < aryTmp.length; ++i) {
            String str = aryTmp[i].trim();
            if (!str.equals("")) {
                if (isSecure) {
                    str = filterInject(str);
                    if (!str.equals("")) {
                        rtn = rtn + str + ",";
                    }
                } else {
                    rtn = rtn + str + ",";
                }
            }
        }
        if (rtn.length() > 0) {
            rtn = rtn.substring(0, rtn.length() - 1);
        }

        return rtn;
    }
}

